`timescale 1ps/1ps
module en_backend (
    input  [127:0] txt
,   input  [127:0] key
,   input  [1:0]   j
,   input          last
,   output [31:0]  out //按列排
);
wire[7:0]f00;wire[7:0]f10;wire[7:0]f20;wire[7:0]f30;  
wire[7:0]f01;wire[7:0]f11;wire[7:0]f21;wire[7:0]f31;  
wire[7:0]f02;wire[7:0]f12;wire[7:0]f22;wire[7:0]f32;  
wire[7:0]f03;wire[7:0]f13;wire[7:0]f23;wire[7:0]f33;

wire[7:0]k00;wire[7:0]k10;wire[7:0]k20;wire[7:0]k30;  
wire[7:0]k01;wire[7:0]k11;wire[7:0]k21;wire[7:0]k31;  
wire[7:0]k02;wire[7:0]k12;wire[7:0]k22;wire[7:0]k32;  
wire[7:0]k03;wire[7:0]k13;wire[7:0]k23;wire[7:0]k33;

map map_txt(txt,f00,f01,f02,f03,f10,f11,f12,f13,f20,f21,f22,f23,f30,f31,f32,f33);
map map_key(key,k00,k01,k02,k03,k10,k11,k12,k13,k20,k21,k22,k23,k30,k31,k32,k33);

reg [7:0] txt_rank [0:3];
reg [7:0] key_col  [0:3];
/*
   j=0 00  11  22  33
   j=1 01  12  23  30
   j=2 02  13  20  31
   j=3 03  10  21  32
*/
always @(*) begin
    case(j)
        2'b00:begin
            txt_rank[0]=f00;txt_rank[1]=f11;txt_rank[2]=f22;txt_rank[3]=f33; 
            key_col [0]=k00;key_col [1]=k10;key_col [2]=k20;key_col [3]=k30;
        end
        2'b01:begin
            txt_rank[0]=f01;txt_rank[1]=f12;txt_rank[2]=f23;txt_rank[3]=f30; 
            key_col [0]=k01;key_col [1]=k11;key_col [2]=k21;key_col [3]=k31;
        end
        2'b10:begin
            txt_rank[0]=f02;txt_rank[1]=f13;txt_rank[2]=f20;txt_rank[3]=f31; 
            key_col [0]=k02;key_col [1]=k12;key_col [2]=k22;key_col [3]=k32; 
        end
        2'b11:begin
            txt_rank[0]=f03;txt_rank[1]=f10;txt_rank[2]=f21;txt_rank[3]=f32;
            key_col [0]=k03;key_col [1]=k13;key_col [2]=k23;key_col [3]=k33; 
        end
    endcase
end

wire [7:0] byte_02_0;wire [7:0] byte_03_0;
wire [7:0] byte_02_1;wire [7:0] byte_03_1;
wire [7:0] byte_02_2;wire [7:0] byte_03_2;
wire [7:0] byte_02_3;wire [7:0] byte_03_3;
wire [31:0] noraml ;

byte0203 byte0203_u0(txt_rank[0],byte_02_0,byte_03_0);
byte0203 byte0203_u1(txt_rank[1],byte_02_1,byte_03_1);
byte0203 byte0203_u2(txt_rank[2],byte_02_2,byte_03_2);
byte0203 byte0203_u3(txt_rank[3],byte_02_3,byte_03_3);

assign noraml[31:24] = byte_02_0   ^ byte_03_1   ^ txt_rank[2] ^ txt_rank[3];
assign noraml[23:16] = txt_rank[0] ^ byte_02_1   ^ byte_03_2   ^ txt_rank[3];
assign noraml[15: 8] = txt_rank[0] ^ txt_rank[1] ^ byte_02_2   ^ byte_03_3  ;
assign noraml[ 7: 0] = byte_03_0   ^ txt_rank[1] ^ txt_rank[2] ^ byte_02_3  ;

assign out[31:24] =(last ? txt_rank[0] : noraml[31:24]) ^ key_col[0];
assign out[23:16] =(last ? txt_rank[1] : noraml[23:16]) ^ key_col[1];
assign out[15: 8] =(last ? txt_rank[2] : noraml[15: 8]) ^ key_col[2];
assign out[ 7: 0] =(last ? txt_rank[3] : noraml[ 7: 0]) ^ key_col[3];

endmodule